home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / irix / tools / vacupd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  10.0 KB  |  404 lines

  1. /*------------------------------------------------------------------------
  2.  * $Id: vacupd.c,v 1.1 1993/10/25 13:15:51 carlson Exp $
  3.  *
  4.  * A program to read and modify data in the vacation database files.
  5.  *
  6.  * Revision History:
  7.  *    $Log: vacupd.c,v $
  8.  * Revision 1.1  1993/10/25  13:15:51  carlson
  9.  * Initial revision
  10.  *
  11.  *------------------------------------------------------------------------*/
  12.  
  13. #include <stdio.h>
  14. #include <errno.h>
  15. #include <stdlib.h>
  16. #include <ndbm.h>
  17. #include <limits.h>
  18. #include <ctype.h>
  19. #include <string.h>
  20. #include <sys/types.h>
  21. #include <time.h>
  22. #include <sys/file.h>
  23. #include <strings.h>
  24.  
  25. /*------------------------------------------------------------------------
  26.  * DDDD   EEEEE  FFFFF   III   N   N  EEEEE   SSS
  27.  * D   D  E      F        I    NN  N  E      S   S
  28.  * D   D  E      F        I    NN  N  E      S
  29.  * D   D  EEE    FFF      I    N N N  EEE     SSS
  30.  * D   D  E      F        I    N  NN  E          S
  31.  * D   D  E      F        I    N  NN  E      S   S
  32.  * DDDD   EEEEE  F       III   N   N  EEEEE   SSS
  33.  *------------------------------------------------------------------------*/
  34.  
  35. /* #define DEBUG */
  36.  
  37. #define MAXLINE    BUFSIZ
  38. #define VMSG    ".vacation.msg"        /* vacation message */
  39. #define VACAT    ".vacation"        /* dbm's database prefix */
  40. #define VDIR    ".vacation.dir"        /* dbm's DB prefix, part 1 */
  41. #define VPAG    ".vacation.pag"        /* dbm's DB prefix, part 2 */
  42.  
  43. /*------------------------------------------------------------------------
  44.  *  SSS   TTTTT  RRRR   U   U   CCC   TTTTT  U   U  RRRR   EEEEE   SSS
  45.  * S   S    T    R   R  U   U  C   C    T    U   U  R   R  E      S   S
  46.  * S        T    R   R  U   U  C        T    U   U  R   R  E      S
  47.  *  SSS     T    RRRR   U   U  C        T    U   U  RRRR   EEE     SSS
  48.  *     S    T    R R    U   U  C        T    U   U  R R    E          S
  49.  * S   S    T    R  R   U   U  C   C    T    U   U  R  R   E      S   S
  50.  *  SSS     T    R   R   UUU    CCC     T     UUU   R   R  EEEEE   SSS
  51.  *------------------------------------------------------------------------*/
  52.  
  53. /*----
  54.  * This structure is used within vacation.c to keep a list of
  55.  * aliases for the current user.  The list is derived from
  56.  * the command line (-a option) and the password file.
  57.  *----*/
  58.  
  59. typedef struct alias {
  60.     struct alias    *next;
  61.     char        *name;
  62. } ALIAS;
  63.  
  64. /*----
  65.  * This is my little structure for keeping the information
  66.  * found in the database.
  67.  *    key        The key.  This is the name of the sender complete
  68.  *            with the path.
  69.  *    date        The date the first vacation message was sent to
  70.  *            the sender.
  71.  *----*/
  72.  
  73. typedef struct record {
  74.     char        *key;
  75.     time_t        date;
  76.     struct record    *next;
  77. } RECORD;
  78.  
  79. /*------------------------------------------------------------------------
  80.  *  GGG   L       OOO   BBBB    AAA   L       SSS
  81.  * G   G  L      O   O  B   B  A   A  L      S   S
  82.  * G      L      O   O  B   B  A   A  L      S
  83.  * G      L      O   O  BBBB   AAAAA  L       SSS
  84.  * G GGG  L      O   O  B   B  A   A  L          S
  85.  * G   G  L      O   O  B   B  A   A  L      S   S
  86.  *  GGG   LLLLL   OOO   BBBB   A   A  LLLLL   SSS
  87.  *------------------------------------------------------------------------*/
  88.  
  89. ALIAS *names = NULL;
  90. RECORD *records = NULL;
  91.  
  92. /*------------------------------------------------------------------------
  93.  * L       OOO    CCC    AAA   L       SSS
  94.  * L      O   O  C   C  A   A  L      S   S
  95.  * L      O   O  C      A   A  L      S
  96.  * L      O   O  C      AAAAA  L       SSS
  97.  * L      O   O  C      A   A  L          S
  98.  * L      O   O  C   C  A   A  L      S   S
  99.  * LLLLL   OOO    CCC   A   A  LLLLL   SSS
  100.  *------------------------------------------------------------------------*/
  101.  
  102. static DBM *db;
  103.  
  104. static char    *VIT = "__VACATION__INTERVAL__TIMER__";
  105. static char    *ProgName;
  106. static char    buffer[MAXLINE];
  107. static time_t    VIT_interval;
  108.  
  109. /*------------------------------------------------------------------------
  110.  * Linked list insert command
  111.  *------------------------------------------------------------------------*/
  112.  
  113. void addItem (datum key, time_t then)
  114. {
  115.     RECORD        *currentR;
  116.  
  117.     if (records)
  118.     {
  119.     for (currentR = records; currentR->next; currentR = currentR->next);
  120.     currentR->next = malloc (sizeof (RECORD));
  121.     currentR = currentR->next;
  122.     }
  123.     else
  124.     {
  125.     records = malloc (sizeof (RECORD));
  126.     currentR = records;
  127.     }
  128.     currentR->next = NULL;
  129.     currentR->key = malloc (key.dsize + 1);
  130.     strncpy (currentR->key, key.dptr, key.dsize);
  131.     currentR->key[key.dsize] = '\0';
  132.     currentR->date = then;
  133. }
  134.  
  135. /*------------------------------------------------------------------------
  136.  * Linked list remove command
  137.  *------------------------------------------------------------------------*/
  138.  
  139. void removeItem (datum key)
  140. {
  141.     RECORD        *currentR, *previousR;
  142.     char        *item = NULL;
  143.  
  144.     for (previousR = NULL, currentR = records; currentR;
  145.      currentR = currentR->next)
  146.     {
  147.     item = malloc (key.dsize + 1);
  148.     strncpy (item, key.dptr, key.dsize);
  149.     item[key.dsize] = '\0';
  150.  
  151.     if (strcmp (item, currentR->key) == 0)
  152.         break;
  153.  
  154.     free (item);
  155.     previousR = currentR;
  156.     }
  157.  
  158.     if (item)
  159.     free (item);
  160.  
  161.     if (currentR)
  162.     {
  163.     if (previousR)
  164.         previousR->next = currentR->next;
  165.     else
  166.         records = currentR->next;
  167.  
  168.     free (currentR->key);
  169.     }
  170. }
  171.  
  172. /*------------------------------------------------------------------------
  173.  * Print collected info.
  174.  *------------------------------------------------------------------------*/
  175.  
  176. void print_info (void)
  177. {
  178.     int            i;
  179.     char        *cptr;
  180.     RECORD        *currentR;
  181.     int            days, hours, minutes, seconds;
  182.  
  183.     printf ("Interval set to:\n");
  184.     i = VIT_interval;
  185.     minutes = i / 60;
  186.     seconds = i - (minutes * 60);
  187.     hours = minutes / 60;
  188.     minutes -= hours * 60;
  189.     days = hours / 24;
  190.     hours -= days * 24;
  191.     printf ("  %d days, %d hours, %d minutes, %d seconds\n", days, hours,
  192.         minutes, seconds);
  193.  
  194.     printf ("Keys found:\n");
  195.     for (currentR = records; currentR; currentR = currentR->next)
  196.     {
  197.     cptr = ctime (¤tR->date);
  198.     printf ("  %s\t%s", currentR->key, cptr);
  199.     }
  200. }
  201.  
  202. /*------------------------------------------------------------------------
  203.  * Provide menu of commands and process.
  204.  *------------------------------------------------------------------------*/
  205.  
  206. int do_menu (void)
  207. {
  208.     int            do_again = 1;
  209.     char        inline[20];
  210.     datum        key, data;
  211.     time_t        then;
  212.     RECORD        *currentR = NULL;
  213.     char        *cptr;
  214.     int            i, choice;
  215.  
  216.     printf ("\nMenu:\n");
  217.     printf ("1    Add user\n");
  218.     printf ("2    Add ignore user\n");
  219.     printf ("3    Remove user\n");
  220.     printf ("4    Print current contents\n");
  221.     printf ("99   Quit\n");
  222.  
  223.     printf ("\nEnter option: ");
  224.     gets (inline);
  225.     printf ("\n");
  226.  
  227.     switch (choice = atoi (inline))
  228.     {
  229.       case 1:                /* Add user */
  230.       case 2:                /* Add ignore user */
  231.     printf ("Enter user name: ");
  232.     gets (inline);
  233.     cptr = inline + strlen (inline) - 1;
  234.     while (iscntrl (*cptr))
  235.         *cptr++ = '\0';
  236.     key.dptr = inline;
  237.     key.dsize = strlen (inline);
  238.  
  239.     then = (choice == 2) ? LONG_MAX : time (NULL);
  240.     data.dptr = (char *)&then;
  241.     data.dsize = sizeof (then);
  242.     i = dbm_store (db, key, data, DBM_INSERT);
  243.     if (i)
  244.     {
  245.         fprintf (stderr, "*** Error %d inserting record.\n", i);
  246.     }
  247.     else
  248.     {
  249.         addItem (key, then);
  250.     }
  251.     break;
  252.  
  253.       case 3:                /* Remove user */
  254.     printf ("Enter user name: ");
  255.     gets (inline);
  256.     cptr = inline + strlen (inline) - 1;
  257.     while (iscntrl (*cptr))
  258.         *cptr++ = '\0';
  259.     key.dptr = inline;
  260.     key.dsize = strlen (inline);
  261.  
  262.     i = dbm_delete (db, key);
  263.     if (i)
  264.     {
  265.         fprintf (stderr, "*** Error %d deleting record\n", i);
  266.     }
  267.     else
  268.     {
  269.         removeItem (key);
  270.     }
  271.     break;
  272.  
  273.       case 4:                /* Print current contents */
  274.     print_info ();
  275.     break;
  276.  
  277.       case 99:                /* Quit */
  278.     do_again = 0;
  279.     break;
  280.  
  281.       default:
  282.     fprintf (stderr, "*** Unrecognized command\n");
  283.     }
  284.  
  285.     return do_again;
  286. }
  287.  
  288. /*------------------------------------------------------------------------
  289.  * M   M   AAA    III   N   N
  290.  * MM MM  A   A    I    NN  N
  291.  * MM MM  A   A    I    NN  N
  292.  * M M M  AAAAA    I    N N N
  293.  * M   M  A   A    I    N  NN
  294.  * M   M  A   A    I    N  NN
  295.  * M   M  A   A   III   N   N
  296.  *------------------------------------------------------------------------*/
  297.  
  298. main (int argc, char *argv[])
  299. {
  300.     register int    i;
  301.     char        *cptr;
  302.     datum        key, data;
  303.     time_t        then;
  304.     RECORD        *currentR;
  305.  
  306.     /*----
  307.      * Get the name of this program and save in ProgName.
  308.      *----*/
  309.  
  310.     cptr = rindex (argv[0], '/');
  311.     if (cptr)
  312.     cptr++;
  313.     else
  314.     cptr = argv[0];
  315.     ProgName = strdup (cptr);
  316.  
  317.     /*----
  318.      * Check that we can access the directory file.
  319.      *----*/
  320.  
  321.     if (access (VDIR, F_OK))
  322.     {
  323.     fprintf (stderr, "%s: Unable to access %s\n", ProgName, VDIR);
  324.     fprintf (stderr, "\t%s\n", strerror (errno));
  325.     exit (-1);
  326.     }
  327.  
  328.     /*----
  329.      * Open the database.
  330.      *----*/
  331.  
  332.     if (!(db = dbm_open (VACAT, O_RDWR, 0)))
  333.     {
  334.     fprintf (stderr, "%s: Unable to open %s\n", ProgName, VACAT);
  335.     fprintf (stderr, "\t%s\n", strerror (errno));
  336.     exit (-1);
  337.     }
  338.  
  339.     /*----
  340.      * Scan through the keys and put them into my little structure.
  341.      *----*/
  342.  
  343.     for (key = dbm_firstkey (db);
  344.      key.dptr != NULL;
  345.      key = dbm_nextkey (db))
  346.     {
  347.     strncpy (buffer, key.dptr, key.dsize);
  348.     buffer[key.dsize] = '\0';
  349. #ifdef DEBUG
  350.     printf ("[%d]%s = ", key.dsize, buffer);
  351. #endif
  352.  
  353.     data = dbm_fetch (db, key);
  354.     bcopy (data.dptr, (char *)&then, sizeof (then));
  355. #ifdef DEBUG
  356.     cptr = ctime (&then);
  357.     printf ("[%d](%08x)%s\n", data.dsize, then, cptr);
  358. #endif
  359.  
  360.     if (strncmp (key.dptr, VIT, key.dsize) == 0)
  361.     {
  362.         VIT_interval = then;
  363.     }
  364.     else
  365.     {
  366.         addItem (key, then);
  367.     }
  368.     }
  369.  
  370. #ifdef DEBUG
  371.     printf ("Test\n");
  372.     key.dptr = "millard";
  373.     key.dsize = strlen (key.dptr);
  374.     printf ("key = '%s'\n", key.dptr);
  375.     printf ("sizeof (key) = %d\n", key.dsize);
  376.     data = dbm_fetch (db, key);
  377.     if (data.dptr)
  378.     {
  379.     printf ("Key found\n");
  380.     bcopy (data.dptr, (char *)&then, sizeof (then));
  381.     cptr = ctime (&then);
  382.     printf ("    time = (%08x)%s\n", then, cptr);
  383.     }
  384.     else
  385.     {
  386.     printf ("Key not found\n");
  387.     }
  388. #endif
  389.  
  390.     /*----
  391.      * Print out what we have so far.
  392.      *----*/
  393.  
  394.     print_info ();
  395.  
  396.     /*----
  397.      * Print menu of choices.
  398.      *----*/
  399.  
  400.     while (do_menu ());
  401.  
  402.     dbm_close (db);
  403. }
  404.